const path = require('path');
const webpack = require('webpack');
const HmtlWebpackPlugin = require('html-webpack-plugin');
const userConfig = require('./src/config/userConfig');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

// const process = require('process');//全局变量，所以无需使用 require()

/**
 * 入口chunk
 */
const entrys = (() => {
    const entrys = userConfig.apps.reduce((prev, app) => {
        prev[app] = [
            // 'babel-polyfill',//暂不做es5 处理
            path.resolve(userConfig.entryBasePath, app, 'index')
        ]
        return prev;
    }, {});
    return entrys;
})();

/**
 * 文件模板
 */
const htmlWebpackPlugins = (() => {
    const tmplIndexPath = `ejs-compiled-loader!${path.join(userConfig.entryBasePath, '/tmpl/index.ejs')}`;
    const htmls = [];
    userConfig.apps.forEach((app) => {
        const tmplUserScriptPath = `ejs-compiled-loader!${path.join(userConfig.entryBasePath, '/tmpl/userScript.ejs')}`;
        const appHtmls = [
            new HmtlWebpackPlugin({
                title: app, //<%=htmlWebpackPlugin.options.title%>
                filename: `${userConfig.outPutBasePath}/${app}/userScript.js`,
                template: tmplUserScriptPath,
                hash: true,
                cache: true,
                inject: false,//是否注入
                minify: {
                    //删除注释，但是会保留script和style中的注释
                    removeComments: userConfig.isProductionEnv,
                    //从脚本和样式删除的注释
                    removeCommentsFromCDATA: userConfig.isProductionEnv,
                    minifyJS: userConfig.isProductionEnv,
                    minifyCSS: userConfig.isProductionEnv,
                    minifyURLs: userConfig.isProductionEnv
                },
                chunks: [app],
                alwaysWriteToDisk: true
            }),
            new HmtlWebpackPlugin({
                title: app, //<%=htmlWebpackPlugin.options.title%>
                filename: `${userConfig.outPutBasePath}/${app}/index.html`,
                template: tmplIndexPath,
                hash: true,
                cache: true,
                inject: false,//是否注入
                minify: {
                    //删除注释，但是会保留script和style中的注释
                    removeComments: userConfig.isProductionEnv,
                    //从脚本和样式删除的注释
                    removeCommentsFromCDATA: userConfig.isProductionEnv,
                    minifyJS: userConfig.isProductionEnv,
                    minifyCSS: userConfig.isProductionEnv,
                    minifyURLs: userConfig.isProductionEnv
                },
                chunks: [app],
                alwaysWriteToDisk: true
            }),
        ];
        htmls.push(...appHtmls);
    });

    htmls.push(new HmtlWebpackPlugin({
        title: '我的资源站',
        filename: `${userConfig.outPutBasePath}/index.html`,
        template: tmplIndexPath,
        hash: true,
        cache: true,
        inject: false,//是否注入
        minify: {
            //删除注释，但是会保留script和style中的注释
            removeComments: userConfig.isProductionEnv,
            //从脚本和样式删除的注释
            removeCommentsFromCDATA: userConfig.isProductionEnv,
            minifyJS: userConfig.isProductionEnv,
            minifyCSS: userConfig.isProductionEnv,
            minifyURLs: userConfig.isProductionEnv
        },
        chunks: [],
        alwaysWriteToDisk: true
    }));
    return htmls;
})();

const serverSetup = (app) => {
    // app.get('/some/path', function (req, res) {
    //     res.json({
    //         custom: 'response'
    //     });
    // });
    // app.get('/main', (req, res) => {
    //     res.send('test');
    // });
    // userConfig.apps.forEach((app) => {
    //     app.get(`/${app}`, require(path.resolve(userConfig.outPutBasePath, app, 'index.html')));
    // })
}

const devServer = (() => {
    return {
        //设置默认监听端口，如果省略，默认为”8080“
        port: "9999",
        //默认webpack-dev-server会为根文件夹提供本地服务器，如果想为另外一个目录下的文件提供本地服务器，应该在这里设置其所在目录（本例设置到“public"目录）
        contentBase: userConfig.outPutBasePath,
        //在开发单页应用时非常有用，它依赖于HTML5 history API，如果设置为true，所有的跳转将指向index.html
        historyApiFallback: true,
        //设置为true，当源文件改变时会自动刷新页面
        inline: true,
        // setup: serverSetup,
        open: true,
        openPage: `index.html`,
        https: true
    };
})();

const webpackConfig = {
    entry: entrys, //入口文件
    output: {
        path: userConfig.outPutBasePath, //打包后的文件存放位置
        publicPath: '',
        filename: "[name]/js/index.js", //"./[name]/bundle.[chunkhash:4].js",//打包后文件名
        chunkFilename: "[id].js"
    },
    //在一个单独的文件中产生一个完整且功能完全的文件。这个文件具有最好的source map，但是它会减慢打包速度；
    // devtool: "source-map",
    //在一个单独的文件中生成一个不带列映射的map，不带列映射提高了打包速度，但是也使得浏览器开发者工具只能对应到具体的行，不能对应到具体的列（符号），会对调试造成不便；
    devtool: userConfig.isProductionEnv ? false : "cheap-module-source-map",
    //使用eval打包源文件模块，在同一个文件中生成干净的完整的source map。这个选项可以在不影响构建速度的前提下生成完整的sourcemap，但是对打包后输出的JS文件的执行具有性能和安全的隐患。在开发阶段这是一个非常好的选项，在生产阶段则一定不要启用这个选项；
    // devtool: "eval-source-map",
    //这是在打包文件时最快的生成source map的方法，生成的Source Map 会和打包后的JavaScript文件同行显示，没有列映射，和eval-source-map选项具有相似的缺点；
    // devtool: "cheap-module-eval-source-map",
    devServer: devServer,
    //webpack --watch
    // watchOptions: { 
    //     poll: 1000,//监测修改的时间(ms)
    //     aggregateTimeout: 500,//防止重复按键，500毫秒内算按键一次
    //     ignored: /node_modules/,//不监测
    // },
    module: {
        rules: [{
            test: /(\.jsx|\.js)$/,
            use: {
                loader: 'babel-loader?cacheDirectory=true',
                //Babel其实可以完全在 webpack.userConfig.js 中进行配置，但是考虑到babel具有非常多的配置选项，在单一的webpack.userConfig.js文件中进行配置往往使得这个文件显得太复杂，因此一些开发者支持把babel的配置选项放在一个单独的名为 ".babelrc" 的配置文件中
                // options: {
                //     //环境：env react es7新特性，箭头函数等：stage-0
                //     presets: ["env", "react", "stage-0"]
                // }
            },
            exclude: /node_modules/
        },
        {
            test: /\.css$/,
            use: [
                //同一个文件引入多个loader
                {
                    loader: "style-loader"
                },
                {
                    loader: "css-loader",
                    options: {
                        modules: true, //指定启用css modules
                        minimize: true, //启用压缩
                        sourceMap: true, //启用sourcemap
                        localIdentName: '[name]__[local]--[hash:base64:5]', //指定的css的类名格式
                    }
                },
                {
                    //postcss.userConfig.js
                    loader: "postcss-loader"
                }
            ]
        },
        {
            test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
            loader: 'url-loader',
        },
        {
            test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
            loader: 'url-loader',
        },
        {
            test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
            loader: 'url-loader',
        }
        ]
    },
    plugins: [
        //构建前先清理
        // new CleanWebpackPlugin(['dist']),
        //拷贝资源
        new CopyWebpackPlugin([{
            from: __dirname + '/src/res',
            to: __dirname + '/dist/res'
        }]),
        //拷贝被ico
        new CopyWebpackPlugin([{
            from: __dirname + '/favicon.ico',
            to: __dirname + '/dist/favicon.ico'
        }]),
        //http://www.css88.com/doc/webpack/plugins/
        new webpack.BannerPlugin('版权所有，翻版必究'),
        //https://github.com/jantimon/html-webpack-plugin#userConfiguration
        //生成多个html文件，多次声明这个插件在plugins 数组中
        ...htmlWebpackPlugins,
    ]
};
// if (userConfig.isProductionEnv) {
//     webpackConfig.plugins.push(
//         //压缩
//         new webpack.optimize.UglifyJsPlugin({
//             exclude: /userScript.js/,//忽略
//             sourceMap: true,
//         })
//     );
// }

module.exports = webpackConfig;